#!/usr/bin/env python3
"""
智能镜像更新状态管理服务
提供更新检测状态、进度跟踪和前端通知功能
"""

import json
import logging
import threading
import time
from datetime import datetime
from pathlib import Path
from typing import Dict, Any, Optional
from flask import Flask
from flask_socketio import SocketIO, emit

logger = logging.getLogger(__name__)

class ImageUpdateStatusManager:
    """镜像更新状态管理器"""
    
    def __init__(self, socketio: Optional[SocketIO] = None):
        self.socketio = socketio
        self.status_file = Path("/tmp/image_update_status.json")
        self.current_status = self.load_status()
        self._lock = threading.Lock()
    
    def load_status(self) -> Dict[str, Any]:
        """加载更新状态"""
        try:
            if self.status_file.exists():
                with open(self.status_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            else:
                return self._get_default_status()
        except Exception as e:
            logger.warning(f"加载更新状态失败: {e}")
            return self._get_default_status()
    
    def save_status(self):
        """保存更新状态"""
        try:
            with self._lock:
                with open(self.status_file, 'w', encoding='utf-8') as f:
                    json.dump(self.current_status, f, indent=2, ensure_ascii=False)
        except Exception as e:
            logger.error(f"保存更新状态失败: {e}")
    
    def _get_default_status(self) -> Dict[str, Any]:
        """获取默认状态"""
        return {
            "checking": False,
            "updating": False,
            "last_check": None,
            "last_update": None,
            "available_updates": [],
            "current_operation": None,
            "progress": 0,
            "message": "就绪",
            "error": None,
            "execution_logs": [],  # 新增执行日志
            "intermediate_results": {}  # 新增中间结果
        }
    
    def start_checking(self):
        """开始检查更新"""
        logger.info(f"🎯 [STATUS] 开始镜像更新检查")
        with self._lock:
            self.current_status.update({
                "checking": True,
                "updating": False,
                "current_operation": "检查镜像更新",
                "progress": 0,
                "message": "正在检查镜像更新...",
                "error": None
            })
        self.save_status()
        logger.info(f"💾 [STATUS] 状态已保存到文件")
        self._notify_frontend("update_status", self.current_status)
        logger.info(f"📡 [STATUS] 已通知前端开始检查状态")
    
    def update_check_progress(self, progress: int, message: str):
        """更新检查进度"""
        logger.info(f"📈 [STATUS] 进度更新: {progress}% - {message}")
        with self._lock:
            self.current_status.update({
                "progress": progress,
                "message": message
            })
        self.save_status()
        self._notify_frontend("update_progress", {
            "progress": progress,
            "message": message
        })
        logger.debug(f"📡 [STATUS] 已推送进度到前端: {progress}%")
    
    def finish_checking(self, available_updates: list, error: str = None):
        """完成检查"""
        if error:
            logger.error(f"❌ [STATUS] 检查完成 - 发生错误: {error}")
        else:
            logger.info(f"🎉 [STATUS] 检查完成 - 发现 {len(available_updates)} 个更新")
            if available_updates:
                for update in available_updates:
                    logger.info(f"🆕 [STATUS] 发现更新: {update.get('name', 'unknown')} - {update.get('reason', 'no reason')}")
        
        with self._lock:
            self.current_status.update({
                "checking": False,
                "last_check": datetime.now().isoformat(),
                "available_updates": available_updates,
                "progress": 100,
                "message": f"检查完成，发现 {len(available_updates)} 个更新" if not error else f"检查失败: {error}",
                "error": error,
                "current_operation": None
            })
        self.save_status()
        logger.info(f"💾 [STATUS] 最终状态已保存")
        self._notify_frontend("check_complete", {
            "available_updates": available_updates,
            "error": error
        })
        logger.info(f"📡 [STATUS] 已通知前端检查完成")
    
    def update_download_progress(self, progress: int, message: str):
        """更新下载进度"""
        with self._lock:
            self.current_status.update({
                "progress": progress,
                "message": message,
                "updating": progress < 100
            })
        self.save_status()
        self._notify_frontend("download_progress", {
            "progress": progress,
            "message": message
        })
    
    def finish_updating(self, success: bool, error: str = None):
        """完成更新"""
        with self._lock:
            self.current_status.update({
                "updating": False,
                "last_update": datetime.now().isoformat() if success else self.current_status.get("last_update"),
                "progress": 100 if success else self.current_status.get("progress", 0),
                "message": "更新完成，容器已重启" if success else f"更新失败: {error}",
                "error": error if not success else None,
                "current_operation": None,
                "available_updates": [] if success else self.current_status.get("available_updates", [])
            })
        self.save_status()
        self._notify_frontend("update_complete", {
            "success": success,
            "error": error
        })
    
    def get_status(self) -> Dict[str, Any]:
        """获取当前状态"""
        with self._lock:
            return self.current_status.copy()
    
    def get_current_status(self) -> Dict[str, Any]:
        """获取当前状态（别名方法，兼容智能更新API）"""
        return self.get_status()
    
    def add_execution_log(self, log_type: str, message: str, details: Dict[str, Any] = None):
        """添加执行日志"""
        log_entry = {
            "timestamp": datetime.now().isoformat(),
            "type": log_type,  # info, success, warning, error
            "message": message,
            "details": details or {}
        }
        
        with self._lock:
            if "execution_logs" not in self.current_status:
                self.current_status["execution_logs"] = []
            
            self.current_status["execution_logs"].append(log_entry)
            
            # 只保留最近50条日志
            if len(self.current_status["execution_logs"]) > 50:
                self.current_status["execution_logs"] = self.current_status["execution_logs"][-50:]
        
        self.save_status()
        self._notify_frontend("execution_log", log_entry)
        logger.info(f"📝 [LOG] {log_type.upper()}: {message}")
    
    def add_intermediate_result(self, step: str, result: Dict[str, Any]):
        """添加中间结果"""
        with self._lock:
            if "intermediate_results" not in self.current_status:
                self.current_status["intermediate_results"] = {}
            
            self.current_status["intermediate_results"][step] = {
                "timestamp": datetime.now().isoformat(),
                "data": result
            }
        
        self.save_status()
        self._notify_frontend("intermediate_result", {
            "step": step,
            "result": result
        })
        logger.info(f"📊 [RESULT] {step}: {len(str(result))} characters")
    
    def clear_logs(self):
        """清空日志和中间结果"""
        with self._lock:
            self.current_status["execution_logs"] = []
            self.current_status["intermediate_results"] = {}
        self.save_status()
        self._notify_frontend("logs_cleared", {})
    
    def _notify_frontend(self, event: str, data: Any):
        """通知前端"""
        if self.socketio:
            try:
                self.socketio.emit(event, data, namespace='/updates')
                logger.info(f"✅ [WebSocket] 通知前端成功: {event} - {data}")
            except Exception as e:
                logger.error(f"❌ [WebSocket] 通知前端失败: {e}")
        else:
            logger.warning(f"⚠️ [WebSocket] SocketIO实例为空，无法发送事件: {event}")
            logger.warning(f"📋 [DEBUG] 事件数据: {data}")

# 全局状态管理器实例
_status_manager = None

def get_status_manager(socketio: Optional[SocketIO] = None) -> ImageUpdateStatusManager:
    """获取状态管理器实例"""
    global _status_manager
    if _status_manager is None:
        _status_manager = ImageUpdateStatusManager(socketio)
    elif socketio and not _status_manager.socketio:
        _status_manager.socketio = socketio
    return _status_manager

def create_update_status_manager(socketio: SocketIO) -> ImageUpdateStatusManager:
    """创建更新状态管理器"""
    return get_status_manager(socketio)